package com.container.core;

import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.container.request.NettyHttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import static com.google.common.base.Preconditions.checkNotNull;

@ChannelHandler.Sharable
class RequestDispatcherHandler extends SimpleChannelInboundHandler<NettyHttpServletRequest> {
    private final Log log = LogFactory.getLog(getClass());
    private final MyServletContext servletContext;

    RequestDispatcherHandler(MyServletContext context) {
        this.servletContext = checkNotNull(context);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext context) throws Exception {
        context.flush();
    }

    @Override
    protected void channelRead0(ChannelHandlerContext context, NettyHttpServletRequest servletRequest) throws Exception {
        HttpServletResponse response = (HttpServletResponse) servletRequest.getServletResponse();
        try {
            NettyRequestDispatcher dispatcher = (NettyRequestDispatcher) servletContext.getRequestDispatcher(servletRequest.getRequestURI());
            //找不到对应的分发器，返回404错误
            if (dispatcher == null) {
                response.sendError(404);
                return;
            }

            dispatcher.dispatch(servletRequest, response);
        } finally {
            if (!servletRequest.isAsyncStarted()) {
                response.getOutputStream().close();
            }
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext context, Throwable t) throws Exception {
        log.error("Unexpected exception caught during request", t);
        context.close();
    }
}